4. The Command Line

Grails의 명령어 시스템은 Gant에 내장되어 있다. Gant는 단순히 Apache Ant의 그루비 래퍼(wrapper)이다.

하지만 관례와 명령어을 사용하기 때문에 Grails가 더 낫다. 다음과 같이 타이핑 했을 때:

grails [command name]

Grails 는 아래에 나오는 디렉토리에서 실행할 Gant 스크립트를 찾는다:

또 Grails는 run-app와 같이 소문자로 되어있는 명령어 이름들을 소문자와 대문자가 섞여있는 형태로 변환할 것이다. 따라서 다음과 같이 치면

grails run-app

다음과 같은 파일들을 찾아낼 것이다:

만약 매치되는 것이 한 개가 아니라면 Grails는 실행할 것을 하나만 고른다. Gant 스크립트가 실행될 때 "default" 타겟이 실행된다.

몇몇 사용 가능한 명령어에 대한 도움말의 목록을 얻으려면 다음과 같이 치면 된다:

grails help

그러면 간단한 사용법과 Grails가 가지고 있는 명령어들이 출력된다:

Usage (optionals marked with *): 
grails [environment]* [target] [arguments]*

Examples: grails dev run-app grails create-app books

Available Targets (type grails help 'target-name' for more info): grails bootstrap grails bug-report grails clean grails compile ...

각각의 명령어들에 관해 더 자세히 알고 싶다면 레퍼런스 가이드의 왼쪽 메뉴에 있는 명령어 레퍼런스를 참조하라.

4.1 Creating Gant Scripts

현재 프로젝트의 루트에서 create-script 명령어를 사용하여 Gant 스크립트를 만들 수 있다. 그 예로 다음과 같이 명령을 내리면

grails create-script compile-sources

script/CompileSources.groovy 라는 스크립트가 만들어질 것이다. Gant 스크립트는 “타겟” 이라는 개념을 지원하고 그것에 의존한다는 것만 제외하면 Groovy 스크립트와 유사하다:

target(default:"The default target is the one that gets executed by Grails") {
	depends(clean, compile)
}
target(clean:"Clean out things") {
	Ant.delete(dir:"output")
}
target(compile:"Compile some sources") {
	Ant.mkdir(dir:"mkdir")
	Ant.javac(srcdir:"src/java", destdir:"output")
}

위의 스크립트에서 보여준 예처럼 Gant 스크립트에는 암묵적으로 Apache Ant API 에 접근 할 수 있는 Ant의 변수가 사용된다.

You can also "depend" on other targets using the depends method demonstrated in the default target above.

4.2 Re-using Grails scripts

Grails에는 재사용하기 매우 좋은 명령어들이 내장돼 있다. 가장 유용한 것들은 compile, package, bootstrap 스크립트이다. 모든 명령어에 대한 정보는 레퍼런스 가이드를 참고하라.

bootstrap 스크립트는 스프링의 ApplicationContext 인스턴스를 통해서 데이터 소스등에 접근할 수 있게 해준다:

Ant.property(environment:"env")                             
grailsHome = Ant.antProject.properties."env.GRAILS_HOME"

includeTargets << new File ( "${grailsHome}/scripts/Bootstrap.groovy" )

target ('default': "Load the Grails interactive shell") { depends( configureProxy, packageApp, classpath, loadApp, configureApp )

Connection c try { // do something with connection c = appCtx.getBean('dataSource').getConnection() } finally { c?.close() } }

4.3 Hooking into Events

Grails는 스크립트 이벤트를 가로채는 방법을 제공한다. Grails의 타겟과 플러그인 스크립트가 실행되는 동안 이벤트가 발생한다.

이 매커니즘은 꽤 단순하고 유연하게loosely 기술된다. 가로챌 이벤트의 목록은 정해진 것이 아니다. 중요한 타겟target 스크립트에는 동일한 이벤트가 없기 때문에 플러그인 스트립트가 발생시킨 이벤트들을 가로챌 수 있다.

Defining event handlers(이벤트 핸들러 정의하기)

이벤트 핸들러는 플러그인의 scripts/ 폴더나 USER_HOME 디렉토리의 .grails/scripts/ 폴더에 있는 Events.groovy라는 스크립트에 정의한다. 모든 이벤트 스크립트는 이벤트가 발생할 때마다 호출된다. 그래서 이벤트를 처리하는 플러그인을 10개를 만들 수도 있고 사용자마다 다르게 할 수도 있다.

eventCreatedArtefact = { type, name ->
   println "Created $type $name"
}

eventStatusUpdate = { msg -> println msg }

eventStatusFinal = { msg -> println msg }

You can see here the three handlers eventCreatedArtefact, eventStatusUpdate, eventStatusFinal. Grails provides some standard events, which are documented in the command line reference guide. For example the compile command fires the following events:

Triggering events

To trigger an event simply include the Init.groovy script and call the event() closure:

Ant.property(environment:"env")
grailsHome = Ant.antProject.properties."env.GRAILS_HOME"
includeTargets << new File ( "${grailsHome}/scripts/Init.groovy" )

event("StatusFinal", ["Super duper plugin action complete!"])

Common Events

Below is a table of some of the common events that can be leveraged:

EventParametersDescription
StatusUpdatemessagePassed a string indicating current script status/progress
StatusErrormessagePassed a string indicating an error message from the current script
StatusFinalmessagePassed a string indicating the final script status message, i.e. when completing a target, even if the target does not exit the scripting environment
CreatedArtefactartefactType,artefactNameCalled when a create-xxxx script has completed and created an artefact
CreatedFilefileNameCalled whenever a project source filed is created, not including files constantly managed by Grails
ExitingreturnCodeCalled when the scripting environment is about to exit cleanly
PluginInstalledpluginNameCalled after a plugin has been installed
CompileStartkindCalled when compilation starts, passing the kind of compile - source or tests
CompileEndkindCalled when compilation is finished, passing the kind of compile - source or tests
DocStartkindCalled when documentation generation is about to start - javadoc or groovydoc
DocEndkindCalled when documentation generation has ended - javadoc or groovydoc
SetClasspathrootLoaderCalled during classpath initialization so plugins can augment the classpath with rootLoader.addURL(...). Note that this augments the classpath after event scripts are loaded so you cannot use this to load a class that your event script needs to import, although you can do this if you load the class by name.
PackagingEndnoneCalled at the end of packaging (which is called prior to the Jetty server being started and after web.xml is generated)
ConfigureJettyJetty Server objectCalled after initial configuration of the Jetty web server.

4.4 Ant and Maven

Ant Integration

create-app 명령어로 Grails 어플리케이션을 만들때 Grails는 자동으로 create-appbuild.xml 파일을 생성한다. 여기에는 다음과 같은 타겟들이 포함돼 있다.

이 타겟들은 Ant에 의해 실행된다:

ant war

build.xml은 Grails의 일반적인 명령어들을 실행하고 CruiseControl 이나 Hudson 같은 CI(continuous integration) 서버와 통합하는데 사용될 수 있다.

Maven Integration

Grails는 공식적으로 Maven 을 지원하지 않는다. 하지만 Grails를 위한 Maven Tools for Grails 라는 프로젝트가 있다. 이 도구는 이 기존의 Grails 프로젝트를 위한 POM을 만들어줄 뿐만아니라 Maven 라이프사이클lifecycle을 Grails에서 사용할 수 있게 해준다.

Grails를 위한 Maven Tools for Grails 에 대한 자세한 정보는 프로젝트 사이트를 참고하라.